﻿using MiniFox.Components;
using MiniFox.Web;
using Wechat.Corp.Auth.Configurations;
using Wechat.Corp.Auth.Models;

namespace Wechat.Corp.Auth.Services
{
    /// <summary>
    /// 
    /// </summary>
    public class WechatAgentAuthService : WechatAgentService, IWechatAgentAuthService
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        public WechatAgentAuthService(string name) : base(name)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="setting"></param>
        public WechatAgentAuthService(IWechatAgent setting) : base(setting)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        [AutoConfigure]
        protected WechatCorpAuthConfiguration AuthConfiguration { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public Uri OpenAuthUri
        {
            get
            {
                return new Uri(AuthConfiguration.OpenAuthUri);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public Uri QrAuthUri
        {
            get
            {
                return new Uri(AuthConfiguration.QrAuthUri);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public Uri SessionUri
        {
            get
            {
                return new Uri(AuthConfiguration.SessionUri);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public Uri UserInfoUri
        {
            get
            {
                return new Uri(AuthConfiguration.UserInfoUri);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="redirectUri"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public string CreateRedirectUri(string redirectUri, string state)
        {
            return CreateRedirectUri(redirectUri, state, AuthMode.Default);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="redirectUri"></param>
        /// <param name="state"></param>
        /// <param name="authMode"></param>
        /// <returns></returns>
        public virtual string CreateRedirectUri(string redirectUri, string state, AuthMode authMode)
        {
            Uri uri = authMode switch
            {
                AuthMode.QrCode => this.QrAuthUri.AddQueryString(new
                {
                    appid = CorpID,
                    agentid = this.AgentID,
                    redirect_uri = redirectUri,
                    state
                }),
                AuthMode.Default => this.OpenAuthUri.AddQueryString(new
                {
                    appid = CorpID,
                    redirect_uri = redirectUri,
                    response_type = "code",
                    scope = this.Setting.AuthScope,
                    state
                }),
                _ => this.OpenAuthUri.AddQueryString(new
                {
                    appid = CorpID,
                    redirect_uri = redirectUri,
                    response_type = "code",
                    scope = this.Setting.AuthScope,
                    state
                }),
            };
            return uri.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="authCode"></param>
        /// <returns></returns>
        public Task<SessionResponse> GetSessionAsync(string authCode)
        {
            string accessToken = this.AccessToken;
            var uri = this.SessionUri.AddQueryString(new { access_token = accessToken, js_code = authCode, grant_type = "authorization_code" });
            return HttpGetAsync<SessionResponse>(uri);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="authCode"></param>
        /// <returns></returns>
        public Task<UserInfoResponse> GetUserInfoAsync(string authCode)
        {
            string accessToken = this.AccessToken;
            var uri = this.UserInfoUri.AddQueryString(new { access_token = accessToken, code = authCode });
            return HttpGetAsync<UserInfoResponse>(uri);
        }

    }
}
